package com.zhentao.studyim.service;

import com.zhentao.studyim.dto.LoginRequest;
import com.zhentao.studyim.dto.RegisterRequest;
import com.zhentao.studyim.entity.User;
import com.zhentao.studyim.repository.UserRepository;
import com.zhentao.studyim.util.JwtUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * 用户业务逻辑服务类
 */
@Service
@RequiredArgsConstructor  // Lombok注解，自动生成构造函数
public class UserService {

    // 依赖注入，final字段会通过构造函数注入
    private final UserRepository userRepository;
    private final JwtUtil jwtUtil;
    private final RedisService redisService;

    /**
     * 用户注册
     * @param request 注册请求数据
     * @return 包含token和用户信息的Map
     */
    @Transactional
    public Map<String, Object> register(RegisterRequest request) {
        try {
            // 1. 检查用户名是否已存在
            boolean userExists = userRepository.existsByUsername(request.getUsername());
            if (userExists) {
                throw new RuntimeException("用户名已存在");
            }

            // 2. 创建新用户
            User user = new User();

            // 设置必填字段
            user.setUsername(request.getUsername());
            user.setPassword(request.getPassword());
            user.setNickname(request.getNickname() != null && !request.getNickname().trim().isEmpty() ?
                    request.getNickname() : request.getUsername());

            // 设置时间字段
            LocalDateTime now = LocalDateTime.now();
            user.setCreateTime(now);
            user.setUpdateTime(now);

            // 设置默认值
            user.setUserType("00");
            user.setSex("2");
            user.setStatus(0);
            user.setDelFlag("0");
            user.setUserStatus(User.UserStatus.OFFLINE);

            // 3. 保存到数据库
            User savedUser = userRepository.save(user);
            userRepository.flush();

            // 4. 生成JWT令牌
            String token = jwtUtil.generateToken(savedUser.getUserId(), savedUser.getUsername());

            // 5. 返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("token", token);
            result.put("user", savedUser);

            return result;

        } catch (Exception e) {
            throw e;
        }
    }

    /**
     * 用户登录
     * @param request 登录请求数据
     * @return 包含token和用户信息的Map
     */
    @Transactional
    public Map<String, Object> login(LoginRequest request) {
        try {
            // 1. 查找用户
            Optional<User> userOpt = userRepository.findByUsername(request.getUsername());

            if (userOpt.isEmpty()) {
                throw new RuntimeException("用户名或密码错误");
            }

            User user = userOpt.get();

            if (!user.getPassword().equals(request.getPassword())) {
                throw new RuntimeException("用户名或密码错误");
            }

            // 2. 更新用户状态
            user.setLoginDate(LocalDateTime.now());
            user.setUserStatus(User.UserStatus.ONLINE);
            userRepository.save(user);

            // 3. 生成JWT令牌
            String token = jwtUtil.generateToken(user.getUserId(), user.getUsername());

            // 4. 尝试设置Redis状态（不影响主要流程）
            try {
                redisService.setUserOnline(user.getUserId());

                Map<String, Object> sessionData = new HashMap<>();
                sessionData.put("loginTime", LocalDateTime.now().toString());
                sessionData.put("username", user.getUsername());
                sessionData.put("nickname", user.getNickname());
                redisService.setUserSession(user.getUserId(), sessionData);
            } catch (Exception redisError) {
                // Redis操作失败不影响登录
            }

            // 5. 返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("token", token);
            result.put("user", user);

            return result;

        } catch (Exception e) {
            throw e;
        }
    }

    /**
     * 用户退出登录
     * @param userId 用户ID
     */
    public void logout(Long userId) {
        Optional<User> userOpt = userRepository.findById(userId);
        if (userOpt.isPresent()) {
            // 1. 更新数据库中的用户状态
            User user = userOpt.get();
            user.setUserStatus(User.UserStatus.OFFLINE);
            userRepository.save(user);

            // 2. 设置用户离线状态
            redisService.setUserOffline(userId);
        }
    }

    /**
     * 根据ID获取用户
     * @param userId 用户ID
     * @return 用户对象
     */
    public User getUserById(Long userId) {
        return userRepository.findById(userId).orElse(null);
    }

    /**
     * 检查用户是否在线
     * @param userId 用户ID
     * @return true-在线，false-离线
     */
    public boolean isUserOnline(Long userId) {
        return redisService.isUserOnline(userId);
    }

    /**
     * 获取所有用户列表
     * @return 用户列表
     */
    public java.util.List<User> getAllUsers() {
        return userRepository.findAll();
    }
}